package wowmobile;

import environment.Environment;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Random;

class Fight {

    boolean isFight;
    MonsterFight mf;
    private String[] playersActions;

    public Fight(Communication c, Environment e, Player p, String answer) throws IOException {
        isFight = true;
        p.getStats().calibrateStats();
        ArrayList<Player> lp = getPlayers(p, answer);
        playersActions = new String[lp.size()];
        
        ArrayList<Monster> ml = randomMonsters(e.getMonsters(), lp.size());
        
        mf = new MonsterFight(lp, ml);
        sendStartFight(lp, ml);
    }

    void fight() throws IOException{
        Order order;
        String sender, getter;
        int alldied, whichplayer;

        int pozycja = 0; //zmienna bardzo tymczasowa!!!!!!

        while (isFight) {
            clearPlayersActions();
            mf.orderTurns();
            getPlayersActions();
            while (!mf.getOrderQueue().isEmpty()) {
                order = mf.getOrderQueue().remove();

                System.out.print("Potwory: Nazwa, Pozycja, Życie: ");
                for (int i = 0; i < mf.getEnemyList().size(); i++) {
                    System.out.print(mf.getEnemyList().get(i).getName() + ", " + i + ", " + mf.getEnemyList().get(i).getHp());
                }
                System.out.println();
                System.out.print("Gracze: Nazwa, Pozycja, Życie: ");
                for (int i = 0; i < mf.getPlayerList().size(); i++) {
                    System.out.print(mf.getPlayerList().get(i).getStats().getNick() + ", " + i + ", " + mf.getPlayerList().get(i).getStats().getHp());
                }
                System.out.println();

                alldied = mf.allDied();
                if (alldied == 0) {
                    sender = "";
                    getter = "";

                    if (order.isPlayerormonster()) {

                        for (int i = 0; i < mf.getPlayerList().size(); i++) {
                            if (order.getPlayer() == mf.getPlayerList().get(i)) {
                                pozycja = i;
                            }
                        }

                        System.out.print("Trwa tura gracza: " + order.getPlayer().getStats().getNick() + " o pozycji " + pozycja);

                        if (order.getPlayer().getStats().getHp() > 0) {
                            whichplayer = 0;
                            for (int i = 0; i < mf.getPlayerList().size(); i++) {
                                if (mf.getPlayerList().get(i) == order.getPlayer()) {
                                    whichplayer = i;
                                }
                            }

                            getter = playersActions[whichplayer];

                            if (!getter.equals("n")) {
                                sender = mf.playerTurn(order.getPlayer(), (whichplayer + 1) + "," + getter);
                            } else {
                                sender = mf.playerTurn(order.getPlayer(), (whichplayer + 1) + ",0,0,0");
                            }
                        } else {
                            System.out.print("... ale ten gracz nie żyje - traci kolejkę.");
                        }
                        System.out.println();
                    } else {

                        for (int i = 0; i < mf.getEnemyList().size(); i++) {
                            if (order.getMonster() == mf.getEnemyList().get(i)) {
                                pozycja = i;
                            }
                        }

                        System.out.print("Trwa tura potwora: " + order.getMonster().getName() + " o pozycji " + pozycja);

                        if (order.getMonster().getHp() > 0) {
                            sender = mf.aiTurn(order.getMonster());
                        } else {
                            System.out.print("... ale ten potwór nie żyje - traci kolejkę.");
                        }
                        System.out.println();
                    }

                    sendToAll(sender);

                } else {
                    if (alldied == 1) {

                        System.out.println("Wygrali gracze.");

                        sender = "F";
                        isFight = false;
                        updateQuests();
                        sendToAll(sender);
                        getOutOfFight(mf.getPlayerList());
                    } else {

                        System.out.println("Wygrały potwory.");

                        sender = "F";
                        isFight = false;
                        sendToAll(sender);
                        getOutOfFight(mf.getPlayerList());
                    }
                }
            }
        }
    }

    private synchronized ArrayList<Player> getPlayers(Player p, String answer) throws IOException {
        ArrayList<Player> tmp1 = new ArrayList<Player>();
        List<Player> tmp2;
        try {
            tmp2 = p.getParty().getPartyList();
        } catch (NullPointerException e) {
            tmp2 = new ArrayList<Player>();
            tmp2.add(p);
        }
        Player play;

        for (int i = 0; i < tmp2.size(); i++) {
            play = tmp2.get(i);
            if (!play.isFight()) {
                play.setFight(true);

                    play.getC().sendAnswer(answer);
                
                tmp1.add(play);
            }

        }
        return tmp1;
    }

    private ArrayList<Monster> randomMonsters(ArrayList<Monster> monsters, int size) {
        ArrayList<Monster> tmp = new ArrayList<Monster>();
        Random r = new Random();
        if (size < 6) {
            size += r.nextInt(2);
        }
        Monster tmpM;
        while (size > 0) {
            tmpM = new Monster(monsters.get(r.nextInt(monsters.size())));
            tmp.add(tmpM);
            size--;
        }
        return tmp;
    }

    private void getOutOfFight(List<Player> playerList) {
        for (int i = 0; i < playerList.size(); i++) {
            playerList.get(i).setFight(false);
        }
    }

    private void sendToAll(String s) throws IOException{
        List<Player> tmp = mf.getPlayerList();
        for (int i = 0; i < tmp.size(); i++) {
                tmp.get(i).getC().sendAnswer(s);
        
        }
    }

    private void getPlayersActions() throws IOException {
        Calendar cal = Calendar.getInstance();
        String tmp;
        long time = cal.getTimeInMillis();
        Player p;
        while ((time + 10000 > cal.getTimeInMillis()) && !isFull()) {
            sendToAll("A"); //prosba o akcje
            for (int i = 0; i < playersActions.length; i++) {
                    p = mf.getPlayerList().get(i);
                    tmp=p.getC().getFightAction();
                    if(playersActions[i].equals("n"))
                        playersActions[i]=tmp;
                    else if(!tmp.equals("n"))
                            playersActions[i]=tmp;
            }
            cal = Calendar.getInstance();
        }
        sendToAll("S"); //powiadomienie o zakonczeniu fazy przyjmowania rozkazow
    }

    private boolean isFull() {
        for (int i = 0; i < playersActions.length; i++) {
            if (playersActions[i].equals("n") && mf.getPlayerList().get(i).getStats().getHp() > 0) {
                return false;
            }
        }
        return true;
    }

    private void clearPlayersActions() {
        for (int i = 0; i < playersActions.length; i++) {
            playersActions[i] = "n";
        }
    }

    private void sendStartFight(ArrayList<Player> lp, ArrayList<Monster> ml) throws IOException
    {
        Player tmp;
        for(int i=0; i<lp.size(); i++)
        {
            tmp=lp.get(i);
            tmp.getC().sendStartFight(lp, ml);
            tmp.getC().sendAnswer(Parser.parseFightData(lp, ml, i));

        }

    }

    private void updateQuests()
    {
        for(int i=0; i<mf.getPlayerList().size();i++)
        {
            if(mf.getPlayerList().get(i).getQ().isQuest())
            {
                mf.getPlayerList().get(i).getQ().updateDone(mf.getEnemyList());
                if(mf.getPlayerList().get(i).getQ().isFinished())
                {
                    mf.getPlayerList().get(i).setQ(new Quest());
                }
            }
        }
    }
}
